"use strict";

var router = require("router"),
    TokenService = require("router").TokenService,
    mongo = require('./core/mongoservice'),
    ObjectId = require('mongodb').ObjectID,
    Q = require('q');

function LocationCityService() {
    console.log("LocationCityService constructor");
}
LocationCityService.prototype = Object.create(TokenService.prototype);
LocationCityService.prototype.constructor = LocationCityService;

LocationCityService.prototype.insert = function (request, response, promise) {
    return promise.then(function (self) {
        //self.identify(request, response);
        return self.mongoSave(request.body).then(function (data) {
            return response.send({ request: request, content: data });
        });
    });
};

LocationCityService.prototype.search = function (request, response, promise) {
    return promise.then(function (self) {
        var city = request.params.city;

        var skip = parseInt(request.query.skip);
        var limit = parseInt(request.query.limit);
        var query = request.query.q;

        return self.mongoGetStartsWith(city, query, { skip: skip, limit: limit}).then(function (data) {
            return response.send({ request: request, content: data });
        });
    });
};

LocationCityService.prototype.getByName = function (request, response, promise) {
    return promise.then(function (self) {
        
        var city = request.params.city;
        var skip = parseInt(request.query.skip);
        var limit = parseInt(request.query.limit);

        return self.mongoGetByName(city, { skip: skip, limit: limit}).then(function (data) {
            if(!data) throw new Error("No result.");
            return response.send({ request: request, content: data });
        }).catch(function(err){
            var data =  {name: city, neighborhoods: [{ name: "Aucun quartier n'est disponible"}] };
            return response.send({ request: request, content: data });
        });
    });
};

LocationCityService.prototype.list = function (request, response, promise) {
    return promise.then(function (self) {
        var skip = parseInt(request.query.skip);
        var limit = parseInt(request.query.limit);

        return self.mongoGetList({ skip: skip, limit: limit}).then(function (data) {
            return response.send({ request: request, content: data });
        });
    });
};

/*-------------------------------------------------------*/
/*mongo daf*/

LocationCityService.prototype.mongoInsert = function (city) {
    if (!city) throw new Error("city is not defined.");
    if (city._id) throw new Error("city already has id: " + city._id);
    var self = this;

    return mongo.insert('location.cities', city).then(function (cities) {
        var promises = [];
        return require("./researchservice").mongoSave(city.name).then(function () {
            city.neighborhoods.forEach(function (item) {
                promises.push(require("./researchservice").mongoSave(item.name + " " + city.name));
            });
            return Q.all(promises).then(function () {
                return cities[0];
            });
        });
    });
};

LocationCityService.prototype.mongoUpdate = function (city) {
    if (!city) throw new Error("city is not defined.");
    if (!city._id) throw new Error("id is not defined.");
};

LocationCityService.prototype.mongoSave = function (city) {
    if (!city) throw new Error("city is not defined.");
    if (!city.name) throw new Error("name is not defined.");
    var self = this;

    return self.mongoGetByName(city.name).then(function (res) {
        if (res) return self.mongoUpdate(city);
        return self.mongoInsert(city);
    });
};

LocationCityService.prototype.mongoGetStartsWith = function (query, options) {
    if (!query) throw new Error("query is not defined.");

    var opts = {};
    options = options || {}
    if (options.limit) opts.limit = options.limit;
    if (options.skip) opts.skip = options.skip;
    opts.sort = {"name": 1};

    query = query.replace(new RegExp(" ", 'g'), '\\s');
    var regex = new RegExp("^" + query, "ig");

    return mongo.find('location.cities', { name: { $regex: regex} }, opts).then(function (cursor) {
        return Q.ninvoke(cursor, 'toArray');
    });
};

LocationCityService.prototype.mongoGetByName = function (query) {
    return Q.fcall(function(){
        if (!query) throw new Error("query is not defined.");

        query = query.replace(new RegExp(" ", 'g'), '\\s');
        var regex = new RegExp("^" + query + "$", "ig");

        return mongo.findOne('location.cities', { name: { $regex: regex} });
    });
};

LocationCityService.prototype.mongoGetById = function (cityId) {
    if (!cityId) throw new Error("cityId is not defined.");

    return mongo.findOne('location.cities', { _id: new ObjectId(cityId) });
};

LocationCityService.prototype.mongoGetList = function (options) {

    options = options || {};

    var opts = {};
    options = options || {}
    if (options.limit) opts.limit = options.limit;
    if (options.skip) opts.skip = options.skip;
    opts.sort = {"name": 1};

    return mongo.find('location.cities', { }, opts).then(function (cursor) {
        return Q.ninvoke(cursor, 'toArray');
    });
};

exports = module.exports = new LocationCityService();